package org.mspring.mlog.service;

import org.mspring.mlog.cache.ArticleCacheService;
import org.mspring.mlog.cache.TagCacheService;
import org.mspring.mlog.dao.ArticleEntityDao;
import org.mspring.mlog.entity.ArticleEntity;
import org.mspring.mlog.entity.ArticleTagEntity;
import org.mspring.mlog.entity.TagEntity;
import org.mspring.mlog.entity.UserEntity;
import org.mspring.mlog.common.constants.ArticleStatus;
import org.mspring.mlog.event.EventSender;
import org.mspring.mlog.event.event.ArticleCreateEvent;
import org.mspring.mlog.event.event.ArticleDeleteEvent;
import org.mspring.mlog.event.event.ArticleUpdateEvent;
import org.mspring.nbee.common.PageResult;
import org.mspring.nbee.common.utils.CollectionUtils;
import org.mspring.nbee.db.dao.sql.builder.part.condition.SqlCondition;
import org.mspring.nbee.db.dao.sql.pager.SqlPager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * @author Gao Youbo
 * @since 2014-12-04 17:59:00
 */
@Service
@SuppressWarnings("Duplicates")
public class ArticleEntityService {

    private static final Logger LOG = LoggerFactory.getLogger(ArticleEntityService.class);

    private ArticleEntityDao articleEntityDao;
    private TagEntityService tagEntityService;
    private ArticleTagEntityService articleTagEntityService;
    private ArticleCacheService articleCacheService;
    private TagCacheService tagCacheService;
    private EventSender eventSender;

    public ArticleEntity findById(long id) {
        return articleEntityDao.findById(id);
    }

    public PageResult<ArticleEntity> list(List<SqlCondition> conditions, SqlPager pager) {
        return articleEntityDao.listPage(conditions, pager);
    }

    public PageResult<Long> findArticleByCategory(long categoryId, int page) {
        return articleEntityDao.findArticleByCategory(categoryId, page);
    }

    public PageResult<Long> findArticleByTag(long tagId, int page) {
        return articleEntityDao.findArticleByTag(tagId, page);
    }

    /**
     * 获取文章的点击次数
     *
     * @param articleId
     * @return
     */
    public int getArticleViewCount(long articleId) {
        return articleEntityDao.getArticleViewCount(articleId);
    }

    /**
     * 创建文章
     *
     * @param article
     * @param tags
     * @param currentUser
     * @return
     */
    @Transactional
    public boolean createArticle(ArticleEntity article, List<String> tags, UserEntity currentUser) {
        boolean flag = articleEntityDao.insert(article);
        if (flag) {
            if (CollectionUtils.isNotEmpty(tags)) {
                for (String tagName : tags) {
                    TagEntity tag = tagEntityService.findByName(tagName);
                    if (tag == null) {
                        tag = new TagEntity();
                        tag.setName(tagName);
                        tag.setCreateTime(new Date());
                        tag.setCreateUser(currentUser.getId());
                        tag.setCreateUserName(currentUser.getNickname());
                        tag.setUpdateTime(new Date());
                        tag.setUpdateUser(currentUser.getId());
                        tag.setUpdateUserName(currentUser.getNickname());
                        tagEntityService.insertOrUpdate(tag);
                    }
                    //关联文章标签
                    ArticleTagEntity articleTag = new ArticleTagEntity();
                    articleTag.setArticleId(article.getId());
                    articleTag.setTagId(tag.getId());
                    articleTagEntityService.insert(articleTag);
                }
            }

            articleCacheService.removeLatestArticleList();
            articleCacheService.removeHotArticleList();

            tagCacheService.removeArticleTagList(article.getId());

            // 事件分发
            eventSender.send(new ArticleCreateEvent(article.getId()));
        }
        return flag;
    }

    /**
     * 更新文章
     *
     * @param article
     * @return
     */
    @Transactional
    public boolean updateArticle(ArticleEntity article, List<String> tags, UserEntity currentUser) {
        boolean flag = articleEntityDao.update(article);
        if (flag) {
            articleTagEntityService.deleteByArticle(article.getId()); //先删除文章对应标签管理
            if (CollectionUtils.isNotEmpty(tags)) {
                for (String tagName : tags) {
                    TagEntity tag = tagEntityService.findByName(tagName);
                    if (tag == null) {
                        tag = new TagEntity();
                        tag.setName(tagName);
                        tag.setCreateTime(new Date());
                        tag.setCreateUser(currentUser.getId());
                        tag.setCreateUserName(currentUser.getNickname());
                        tag.setUpdateTime(new Date());
                        tag.setUpdateUser(currentUser.getId());
                        tag.setUpdateUserName(currentUser.getNickname());
                        tagEntityService.insertOrUpdate(tag);
                    }
                    //关联文章标签
                    ArticleTagEntity articleTag = new ArticleTagEntity();
                    articleTag.setArticleId(article.getId());
                    articleTag.setTagId(tag.getId());
                    articleTagEntityService.insert(articleTag);
                }
            }

            articleCacheService.removeLatestArticleList();
            articleCacheService.removeHotArticleList();
            articleCacheService.removeArticle(article.getId());

            tagCacheService.removeArticleTagList(article.getId());

            // 事件分发
            eventSender.send(new ArticleUpdateEvent(article.getId()));
        }
        return flag;
    }

    @Transactional
    public boolean deleteById(long id) {
        ArticleEntity article = articleEntityDao.findById(id);
        if (article == null) {
            throw new NullPointerException("文章不存在");
        }
        article.setStatus(ArticleStatus.DELEtED);
        boolean flag = articleEntityDao.update(article);
        if (flag) {
            articleCacheService.removeLatestArticleList();
            articleCacheService.removeHotArticleList();
            articleCacheService.removeArticle(id);

            // 事件分发
            eventSender.send(new ArticleDeleteEvent(id));
        }
        return flag;
    }

    /**
     * 更新文章的点击率
     *
     * @param articleId
     * @param viewCount
     * @return
     */
    @Transactional
    public boolean updateArticleViewCount(long articleId, int viewCount) {
        return articleEntityDao.updateArticleViewCount(articleId, viewCount);
    }

    @Autowired
    public void setArticleEntityDao(ArticleEntityDao articleEntityDao) {
        this.articleEntityDao = articleEntityDao;
    }

    @Autowired
    public void setTagEntityService(TagEntityService tagEntityService) {
        this.tagEntityService = tagEntityService;
    }

    @Autowired
    public void setArticleTagEntityService(ArticleTagEntityService articleTagEntityService) {
        this.articleTagEntityService = articleTagEntityService;
    }

    @Autowired
    public void setArticleCacheService(ArticleCacheService articleCacheService) {
        this.articleCacheService = articleCacheService;
    }

    @Autowired
    public void setTagCacheService(TagCacheService tagCacheService) {
        this.tagCacheService = tagCacheService;
    }

    @Autowired
    public void setEventSender(EventSender eventSender) {
        this.eventSender = eventSender;
    }
}